
package ploy.compiler;

import java.util.*;

import org.objectweb.asm.*;
import org.objectweb.asm.util.*;
import org.objectweb.asm.commons.*;

import ploy.lang.*;

/**
 * Constant represents constant values in Ploy programs.  They are compiled
 * into instantiations of subclasses of DynamicObject.
 */
class Constant extends AST {

    private DynamicObject value;

    public Constant( DynamicObject s ) {
	value = s;
    }

    public String toString( ) {
	return value.toString();
    }

    /**
     * Generating the bytecode consists merely of instantiating the
     * correct class.
     */
    public FrameSize generateBytecode( MethodVisitor mv ) {
	if ( value.isNumber( ) ) {
	    mv.visitTypeInsn(Opcodes.NEW, ploy.lang.Number.jvmClass);
	    mv.visitInsn(Opcodes.DUP);
	    mv.visitLdcInsn(((ploy.lang.Number)value).getIntValue());
	    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, ploy.lang.Number.jvmClass,
			       "<init>", "(I)V");
	    return new FrameSize( 3, 0 );
	} else if ( value.isString( ) ) {
	    mv.visitTypeInsn(Opcodes.NEW, ploy.lang.DString.jvmClass);
	    mv.visitInsn(Opcodes.DUP);
	    mv.visitLdcInsn(((ploy.lang.DString)value).getStringValue());
	    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, ploy.lang.DString.jvmClass,
			       "<init>", "(Ljava/lang/String;)V");
	    return new FrameSize( 3, 0 );
	} else {
	    mv.visitTypeInsn(Opcodes.NEW, ploy.lang.Number.jvmClass);
	    mv.visitInsn(Opcodes.DUP);
	    mv.visitIntInsn(Opcodes.SIPUSH, 0);
	    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, ploy.lang.Number.jvmClass,
			       "<init>", "(I)V");
	    return new FrameSize( 3, 0 );
	}
    }
}